﻿using System;
using System.Globalization;

namespace Narwhunderful.Aphelia.Framework.IO.Serialization
{
    public sealed class SimpleValueConverter : ISimpleValueConverter
    {
        private readonly CultureInfo _cultureInfo;

        public SimpleValueConverter()
        {
            _cultureInfo = CultureInfo.InvariantCulture;

            // Alternatively
            //_cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
        }

        public SimpleValueConverter(CultureInfo cultureInfo)
        {
            _cultureInfo = cultureInfo;
        }

        public string ConvertToString(object value)
        {
            if (value == null) return string.Empty;

            return Convert.ToString(value, _cultureInfo);
        }

        public object ConvertFromString(string text, Type type)
        {
            try
            {
                if (type == typeof(string)) return text;
                if (type == typeof(Boolean)) return Convert.ToBoolean(text, _cultureInfo);
                if (type == typeof(Byte)) return Convert.ToByte(text, _cultureInfo);
                if (type == typeof(Char)) return Convert.ToChar(text, _cultureInfo);
                if (type == typeof(DateTime)) return Convert.ToDateTime(text, _cultureInfo);
                if (type == typeof(Decimal)) return Convert.ToDecimal(text, _cultureInfo);
                if (type == typeof(Double)) return Convert.ToDouble(text, _cultureInfo);
                if (type == typeof(Int16)) return Convert.ToInt16(text, _cultureInfo);
                if (type == typeof(Int32)) return Convert.ToInt32(text, _cultureInfo);
                if (type == typeof(Int64)) return Convert.ToInt64(text, _cultureInfo);
                if (type == typeof(SByte)) return Convert.ToSByte(text, _cultureInfo);
                if (type == typeof(Single)) return Convert.ToSingle(text, _cultureInfo);
                if (type == typeof(UInt16)) return Convert.ToUInt16(text, _cultureInfo);
                if (type == typeof(UInt32)) return Convert.ToUInt32(text, _cultureInfo);
                if (type == typeof(UInt64)) return Convert.ToUInt64(text, _cultureInfo);
                if (type == typeof(TimeSpan)) return TimeSpan.Parse(text);
                if (type == typeof(Guid)) return new Guid(text);
                if (type.IsEnum) return Enum.Parse(type, text, true);

                throw new InvalidOperationException(string.Format("Unknown simple type: {0}", type.FullName));
            }
            catch (Exception ex)
            {
                throw new SimpleValueParsingException(
                    string.Format("Invalid value: {0}. See details in the inner exception.", text), ex);
            }
        }

    }
}
